//
//  CacheDB.m
//  TravelGuideMdd
//
//  Created by BigPolarBear on 13-5-25.
//  Copyright (c) 2013年 mafengwo.com. All rights reserved.
//

#import "CacheDB.h"
#import "DBHelper.h"
#import "ConstPath.h"

#define kFile_CacheDB                   [NSString stringWithFormat:@"%@/cachedb.sqlite",kPATH_Workshop]

#pragma mark ------ 表0：缓存表
#define kTableColumn_Cache_c_key    @"c_key"
#define kTableColumn_Cache_c_value  @"c_value"
#define kTableColumn_Cache_c_ctime  @"c_ctime"
#define kTableColumn_Cache_c_utime  @"c_utime"

@implementation CacheItem

-(id)initWithDict:(NSDictionary*)dict
{
    if (dict.count == 0) {
        return nil;
    }
    
    self = [super init];
    if (self) {
        NSString* key = [dict valueForKey:kTableColumn_Cache_c_key];
        NSString* value = [dict valueForKey:kTableColumn_Cache_c_value];
        NSString* ctime = [dict valueForKey:kTableColumn_Cache_c_ctime];
        NSString* utime = [dict valueForKey:kTableColumn_Cache_c_utime];
        
        NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
        NSTimeZone *timeZone = [NSTimeZone localTimeZone];
        
        [formatter setTimeZone:timeZone];
        [formatter setDateFormat : @"yyyy-MM-dd HH:mm:ss"];
        
        _key = key;
        _value = value;
        _ctime = [formatter dateFromString:ctime];
        _utime = [formatter dateFromString:utime];
    }
    
    return self;
}

@end


@interface CacheDB()

@property (nonatomic,strong) FMDatabaseQueue* databaseQueue;

@end

@implementation CacheDB


#pragma mark ------ 类的方法

+(CacheDB*)defaultCacheDB
{
    static CacheDB* _defaultCacheDB = nil;
    
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _defaultCacheDB = [[CacheDB alloc] init];
    });
    
    return _defaultCacheDB;
}

+(void)setValue:(NSString*)value forKey:(NSString*)key
{
    [[self defaultCacheDB] setKVCacheValue:value forKey:key];
}
+(NSString*)valueForKey:(NSString*)key
{
    return [[self defaultCacheDB] getKVCacheValueForKey:key];
}

+(void)setValueArray:(NSArray*)array forKey:(NSString*)key
{
    [self setValue:[MFWJsonUtils stringEncodingJsonObject:array] forKey:key];
}
+(NSArray*)valueArrayForKey:(NSString*)key
{
    NSString* json = [self valueForKey:key];
    if (!json) {
        return nil;
    }
    id value = JsonDecode(json);
    if (value && ![value isKindOfClass:[NSArray class]]) {
        // 解析出来的不是需要的类型 todo 是否需要抛异常
        return nil;
    }else{
        return value;
    }
}
/** 设置KV缓存：字典 */
+(void)setValueDict:(NSDictionary*)dict forKey:(NSString*)key
{
    [self setValue:[MFWJsonUtils stringEncodingJsonObject:dict] forKey:key];
}

/** 获取KV缓存：字典 */
+(NSDictionary*)valueDictForKey:(NSString*)key
{
    NSString* json = [self valueForKey:key];
    if (!json) {
        return nil;
    }
    id value = JsonDecode(json);
    if (value && ![value isKindOfClass:[NSDictionary class]]) {
        // 解析出来的不是需要的类型 todo 是否需要抛异常
        return nil;
    }else{
        return value;
    }
}

+(CacheItem*)cacheItemForKey:(NSString*)key
{
    return [[self defaultCacheDB] cacheItemForKey:key];
}


#pragma mark ------ 实例方法
-(id)init
{
    self = [super init];
    if(self)
    {
        self.databaseQueue = [FMDatabaseQueue databaseQueueWithPath:[[self class] database]];
        
        // 创建缓存库
        [self createCacheDB];
    }
    
    return self;
}

+ (NSString*)database
{
    return kFile_CacheDB;
}

-(void)dealloc
{
    [self.databaseQueue close];
    self.databaseQueue = nil;
}

/** 创建缓存库 */
-(void)createCacheDB
{
    @try {
        // 创建缓存库
        [self.databaseQueue inDatabase:^(FMDatabase *db) {
            [DBHelper executeCacheCreateDatabase:db];
        }];
    }
    @catch (NSException *exception) {
        //
        [self.databaseQueue close];
    }
    @finally {
        
    }
}


#pragma mark Key-Value缓存表相关

/** 持久化缓存 */
-(void)setKVCacheValue:(NSString*)value forKey:(NSString*)key
{
    if(key.length == 0){
        // key为空的，直接返回
        return;
    }

    if (!value) {
        // 清除已存在的
        [self.databaseQueue inDatabase:^(FMDatabase *db) {
            [DBHelper executeCacheDeleteForKey:key database:db];
        }];
    }else{
        // 先插入记录，再更新时间戳
        [self.databaseQueue inDatabase:^(FMDatabase *db) {
            [DBHelper executeCacheSetValue:value forKey:key database:db];
        }];
    }
}

/** 返回缓存的value对象 */
-(NSString*)getKVCacheValueForKey:(NSString*)key
{
    __block NSString* retStr = nil;
    
    [self.databaseQueue inDatabase:^(FMDatabase *db) {
        FMResultSet* retSet = [DBHelper executeCacheSelectValueForKey:key database:db];
        
        while ([retSet next]) {
            retStr = [retSet stringForColumn:kTableColumn_Cache_c_value];
            break;
        }
    }];

    return retStr;
}


/** 返回缓存数据：含创建时间、更新时间等 */
-(CacheItem*)cacheItemForKey:(NSString*)key
{
    __block CacheItem* item = nil;
    
    [self.databaseQueue inDatabase:^(FMDatabase *db) {
        FMResultSet* retSet = [DBHelper executeCacheSelectForKey:key database:db];
        while ([retSet next]) {
            item = [[CacheItem alloc]initWithDict:[retSet resultDictionary]];
            break;
        }
    }];

    return item;
}

-(BOOL)deleteAllCache
{
    [self.databaseQueue inDatabase:^(FMDatabase *db) {
        [DBHelper executeCacheDelete:db];
    }];
    return YES;
}

-(NSArray*)listCacheItemWithKeyPrefix:(NSString*)keyPrefix
{
    NSMutableArray* list = [NSMutableArray array];
    
    [self.databaseQueue inDatabase:^(FMDatabase *db) {
        FMResultSet* retSet = [DBHelper executeCacheSelectForKeyPrefix:keyPrefix database:db];
        
        NSMutableArray* list = [NSMutableArray array];
        while ([retSet next]) {
            CacheItem* item = [[CacheItem alloc]initWithDict:[retSet resultDictionary]];
            if (item) {
                [list addObject:item];
            }
        }
    }];

    return list;
}

@end
